package d3s.net.interpolate
{
	import org.papervision3d.core.Number3D;
	
	/**
	 * @author Philippe Ajoux (philippe.ajoux@gmail.com)
	 * @version 05.01.07
	 */
	public class BSplineTween extends Tween
	{
		public function BSplineTween(object:*)
		{
			super(object);
		}
		
		public override function tween(points:Array, time:Number = 1):void
		{
			// Make the the BSpline start and end at first and last point
			points.unshift(points[0]);
			points.unshift(points[0]);
			points.push(points[points.length - 1]);
			points.push(points[points.length - 1]);
			
			super.tween(points, time);
			
			fps = (points.length - 4) / time;
			index = 1;
		}
		
		public override function update(delta:uint):void
		{
			if (points == null)
				return;
			
			if (index + 2 >= points.length)
			{
				index = 1;
				interp = 0;
			}
			
			var t:Number = interp;
			var t2:Number = t * t;
			var t3:Number = t2 * t;
			var k1:Number = 1 - 3 * t + 3 * t2 - t3;
			var k2:Number = 4 - 6 * t2 + 3 * t3;
			var k3:Number = 1 + 3 * t + 3 * t2 - 3 * t3;
			var p0:Number3D, p1:Number3D, p2:Number3D, p3:Number3D;
			
			p0 = points[index - 1];
			p1 = points[index];
			p2 = points[index + 1];
			p3 = points[index + 2];
			
			object.x = 1 / 6.0 * (k1 * p0.x + k2 * p1.x + k3 * p2.x + t3 * p3.x);
			object.y = 1 / 6.0 * (k1 * p0.y + k2 * p1.y + k3 * p2.y + t3 * p3.y);
			object.z = 1 / 6.0 * (k1 * p0.z + k2 * p1.z + k3 * p2.z + t3 * p3.z);
				
			super.update(delta);
		}
	}
}